<html xmlns="http://www.w3.org/1999/html">
<!--
  == This software is subject to the terms of the Eclipse Public License v1.0
  == Agreement, available at the following URL:
  == http://www.eclipse.org/legal/epl-v10.html.
  == You must accept the terms of that agreement to use this software.
  ==
  == Copyright (C) 2005-2011 Pentaho
  == All Rights Reserved.
  -->

<head>
    <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
	<title>Pentaho Analysis Services: Developer's guide</title>
</head>
<body>
<!-- doc2web start -->

<!-- page title -->
<div class="contentheading">Developer's Guide</div>
<!-- end page title -->

<hr noshade size="1">

<p>There are several ways to get Mondrian running. The easiest is to download a
binary release, as described in the <a href="install.html">installation guide</a>.
But you can also build Mondrian from its source code. This document describes
how to do that, how to learn about Mondrian's inner workings, and the guidelines
you'll need to follow if you want to contribute to the Mondrian project.</p>

<h2>Getting the source code<a name="Getting_the_source_code">&nbsp;</a></h2>

<p>First, you need to get a copy of the source code. You can get the source code
from SourceForge or from the project's Github repository.</p>

<h3>Download the latest release<a name="3_3_Download_the_latest_source_release">&nbsp;</a></h3>

<p>Download the latest <code>mondrian-<i>version</i>.zip</code> from <a href="http://sourceforge.net/projects/mondrian">
SourceForge</a>, and unzip. Now find the <code>mondrian-<i>version</i>-src.zip</code>
inside this distribution, and unzip it. The directory you unzip this source code to &mdash;
typically something like <code>C:\open\mondrian</code>
or <code>/usr/local/mondrian-<i>x.y.z</i></code> &mdash; will be denoted <code>
<i>${project.location}</i></code> later in this document.</p>

<h3>Clone the Github repository<a name="3_4_Connect_to_the_GitHub_repository">&nbsp;</a></h3>
<p>Download the Git client from
  <a target="_parent" href="http://www.git-scm.com/downloads">Git</a>.</p>
  <p>Clone the Git repository.</p><pre>
<code>$ git clone https://github.com/pentaho/mondrian.git</code></pre><pre>
    <code>Cloning into 'mondrian'...
    remote: Counting objects: 51661, done.
    remote: Compressing objects: 100% (9979/9979), done.
    remote: Total 51661 (delta 37833), reused 51512 (delta 37691)
    Receiving objects: 100% (51661/51661), 294.25 MiB | 604 KiB/s, done.
    Resolving deltas: 100% (37833/37833), done.</code></pre>


<h2>Building the code</h2>

<h3>Setting up your environment</h3>
<ul>
    <li>Download and install a JDK for Java 1.5, 1.6 and 1.7.
        You can download the releases from
        <a href="http://www.oracle.com/technetwork/java/javase/archive-139210.html">Oracle</a>
        <p><i>Mondrian requires
        all three versions to build correctly.  When Mondrian creates JDBC connections,
        it creates JDBC version 3 connections with Java 1.5, version 4 connections with
        Java 1.6 and version 4.1 connections with Java 1.7.  The factory classes
        that create JDBC connections(FactoryJdbc3Impl, FactoryJdbc4Impl and FactoryJdbc41Impl)
        need to be compiled with the matching JDK version.</i></p>
        </li>
    <li>Download and install Ant version 1.6 or later.  You can download Ant from <a href="http://ant.apache.org/bindownload.cgi">Apache</a></li>
    <li>Setup environment variables <code>JAVA_HOME_15</code>, <code>JAVA_HOME_16</code>,
        <code>JAVA_HOME_17</code> and <code>ANT_HOME</code> to point at the
        locations where you installed them.  Set <code>JAVA_HOME</code> to your Java 1.5 JDK.</li>
</ul>

<p>Now build the code, as follows:</p>

<blockquote>
<pre>
<code>
    C:\mondrian> ant

    Buildfile: C:\mondrian\build.xml

    version:

    antcontrib.download-check:

    antcontrib.download:

    install-antcontrib:

    ivy.download-check:

    ivy.download:

    install-ivy:
    [echo] Installing IVY...

    resolve:
    [echo] symlink=${symlink}
    [ivy:resolve] :: Ivy 2.1.0 - 20090925235825 :: http://ant.apache.org/ivy/ ::
    [ivy:resolve] :: loading settings :: url = file:C:/mondrian/ivysettings.xml
    [ivy:resolve] :: resolving dependencies :: pentaho#mondrian-workbench;TRUNK-SNAPSHOT
    [ivy:resolve] 	confs: [default]
    [ivy:resolve] 	found commons-codec#commons-codec;1.2 in public

    ....more ivy messages

    prepare:
    [mkdir] Created dir: C:\mondrian\build

    define-tasks:

    parser:
    [javacup] Opening files...
    [javacup] Parsing specification from C:\mondrian\src\main\mondrian\olap\Parser.cup...
    [javacup] Checking specification...
    [javacup] Warning: Terminal "UNKNOWN" was declared but never used
    [javacup] Building parse tables...
    [javacup]   Computing non-terminal nullability...
    [javacup]   Computing first sets...
    [javacup]   Building state machine...
    [javacup]   Filling in tables...
    [javacup] *** Reduce/Reduce conflict found in state #98
    [javacup]   between value_expression_primary ::= NULL (*)
    [javacup]   and     term3 ::= term3 IS NULL (*)
    [javacup]   under symbols: {EOF, AND, AS, CELL, DIMENSION, ELSE, END, IN, IS, MATCHES, MEMBER, NOT, ON, OR, PROPERTIES, RETURN, SELECT, SET, THEN, WHEN, XOR, COLON, COMMA, EQ, GE, GT, LE, LT, NE, RBRACE, RPAREN}
    [javacup]   Resolved in favor of the second production.
    [javacup]
    [javacup] *** Shift/Reduce conflict found in state #98
    [javacup]   between value_expression_primary ::= NULL (*)
    [javacup]   under symbol EOF
    [javacup]   Resolved in favor of shifting.

    ....more javacup messages

    [javacup]   Checking for non-reduced productions...
    [javacup] Writing parser...
    [javacup] Closing files...
    [javacup] ------- CUP v0.10k Parser Generation Summary -------
    [javacup]   0 errors and 64 warnings
    [javacup]   69 terminals, 67 non-terminals, and 147 productions declared,
    [javacup]   producing 224 unique parse states.
    [javacup]   1 terminal declared but not used.
    [javacup]   0 non-terminal declared but not used.
    [javacup]   0 productions never reduced.
    [javacup]   63 conflicts detected (63 expected).
    [javacup]   Code written to "Parser.java", and "ParserSym.java".
    [javacup] ---------------------------------------------------- (v0.10k)
    [javacc] Java Compiler Compiler Version 5.0 (Parser Generator)
    [javacc] (type "javacc" with no arguments for help)
    [javacc] Reading from file C:\mondrian\src\main\mondrian\parser\MdxParser.jj . . .
    [javacc] Note: UNICODE_INPUT option is specified. Please make sure you create the parser/lexer using a Reader with the correct character encoding.
    [javacc] File "TokenMgrError.java" does not exist.  Will create one.
    [javacc] File "ParseException.java" does not exist.  Will create one.
    [javacc] File "Token.java" does not exist.  Will create one.
    [javacc] File "SimpleCharStream.java" does not exist.  Will create one.
    [javacc] Parser generated successfully.

    generate.resources:
    [javac] Compiling 7 source files to C:\mondrian\classes
    [resgen] Generating C:\mondrian\src\main\mondrian\resource\MondrianResource.java
    [resgen] Generating C:\mondrian\classes\mondrian\resource\MondrianResource.properties
    [resgen] Generating C:\mondrian\src\main\mondrian\resource\MondrianResource_en_US.java
    [resgen] Generating C:\mondrian\classes\mondrian\resource\MondrianResource_en_US.properties
    [resgen] Generating C:\mondrian\src\main\mondrian\resource\MondrianResource_de_DE.java
    [resgen] Generating C:\mondrian\classes\mondrian\resource\MondrianResource_de_DE.properties
    [resgen] Generating C:\mondrian\src\main\mondrian\resource\MondrianResource_de.java
    [resgen] Generating C:\mondrian\classes\mondrian\resource\MondrianResource_de.properties
    [resgen] Generating C:\mondrian\src\main\mondrian\resource\MondrianResource_es_ES.java
    [resgen] Generating C:\mondrian\classes\mondrian\resource\MondrianResource_es_ES.properties

    generate.properties:
    [javac] Compiling 1 source file to C:\mondrian\classes
    [java] Generating src\main\mondrian\olap\MondrianProperties.java
    [java] Generating doc\properties.html
    [java] Generating mondrian.properties.template

    def:
    [xomgen] Writing C:\mondrian\src\main\mondrian\olap\mondrian.dtd
    [xomgen] Writing C:\mondrian\src\main\mondrian\olap\MondrianDef.java
    [xomgen] Done
    [copy] Copying 1 file to C:\mondrian\lib
    [xomgen] Writing C:\mondrian\src\main\mondrian\gui\mondrian_SW.dtd
    [xomgen] Writing C:\mondrian\src\main\mondrian\gui\MondrianGuiDef.java
    [xomgen] Done
    [copy] Copying 1 file to C:\mondrian\lib
    [xomgen] Writing C:\mondrian\src\main\mondrian\xmla\datasourcesconfig.dtd
    [xomgen] Writing C:\mondrian\src\main\mondrian\xmla\DataSourcesConfig.java
    [xomgen] Done
    [copy] Copying 1 file to C:\mondrian\lib

    compileJdk15:
    [exec] Using ANT_HOME: C:/Java/apache-ant-1.8.4
    [exec] Using JAVA_HOME: C:/Java/jdk1.5.0_22
    [exec] Using JAVACMD: C:/Java/jdk1.5.0_22\bin\java.exe
    [exec] Using Ant arguments: -Drequested.java.version=jdk1.5 compile.java
    [exec] Buildfile: C:\mondrian\build.xml
    [exec]
    [exec] apologise:
    [exec]
    [exec] compile.java:
    [exec]      [echo] Compiling on JVM Version: 1.5.0_22-b03
    [exec]     [javac] Compiling 722 source files to C:\mondrian\classes
    [exec]     [javac] Note: Some input files use or override a deprecated API.
    [exec]     [javac] Note: Recompile with -Xlint:deprecation for details.
    [exec]     [javac] Note: Some input files use unchecked or unsafe operations.
    [exec]     [javac] Note: Recompile with -Xlint:unchecked for details.
    [exec]      [copy] Copying 1 file to C:\mondrian\classes
    [exec]
    [exec] BUILD SUCCESSFUL
    [exec] Total time: 9 seconds

    compileJdk16:
    [exec] Using ANT_HOME: C:/Java/apache-ant-1.8.4
    [exec] Using JAVA_HOME: c:/Java/jdk1.6.0_35
    [exec] Using JAVACMD: c:/Java/jdk1.6.0_35\bin\java.exe
    [exec] Using Ant arguments: -Drequested.java.version=jdk1.6 compile.java
    [exec] Buildfile: C:\mondrian\build.xml
    [exec]
    [exec] apologise:
    [exec]
    [exec] compile.java:
    [exec]      [echo] Compiling on JVM Version: 1.6.0_35-b10
    [exec]     [javac] Compiling 3 source files to C:\mondrian\classes
    [exec]     [javac] Note: C:\mondrian\src\main\mondrian\util\UtilCompatibleJdk16.java uses unchecked or unsafe operations.
    [exec]     [javac] Note: Recompile with -Xlint:unchecked for details.
    [exec]
    [exec] BUILD SUCCESSFUL
    [exec] Total time: 2 seconds

    compileJdk17:
    [exec] Using ANT_HOME: C:/Java/apache-ant-1.8.4
    [exec] Using JAVA_HOME: c:/Java/jdk1.7.0_07
    [exec] Using JAVACMD: c:/Java/jdk1.7.0_07\bin\java.exe
    [exec] Using Ant arguments: -Drequested.java.version=jdk1.7 compile.java
    [exec] Buildfile: C:\mondrian\build.xml
    [exec]
    [exec] apologise:
    [exec]
    [exec] compile.java:
    [exec]      [echo] Compiling on JVM Version: 1.7.0_07-b11
    [exec]     [javac] Compiling 1 source file to C:\mondrian\classes
    [exec]
    [exec] BUILD SUCCESSFUL
    [exec] Total time: 1 second

    compile:

    info:
    [echo] ==============================================================
    [echo] | Mondrian configuration info                                |
    [echo] ==============================================================
    [echo] project.location             = C:\mondrian
    [echo] jdk.home                     = C:/Java/jdk1.5.0_22
    [echo] log4j.configuration          = log4j.properties
    [echo] mondrian.foodmart.catalogURL = file:C:\mondrian/demo/FoodMart.xml
    [echo] mondrian.foodmart.jdbcURL    = jdbc:mysql://localhost/foodmart?user=foodmart&password=foodmart
    [echo] mondrian.jdbcDrivers         = com.mysql.jdbc.Driver
    [echo] driver.classpath (additions) = C:/Java/jdbc/mysql-connector-java-5.1.22-bin.jar
    [echo] ==============================================================

    compile.tests:
    [echo] Test Classpath: C:\mondrian\lib\ant-launcher.jar
    [echo]  C:\mondrian\lib\ant.jar

    ...more classpath messages

    [javac] Compiling 174 source files to C:\mondrian\testclasses
    [javac] Note: Some input files use or override a deprecated API.
    [javac] Note: Recompile with -Xlint:deprecation for details.
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

    check-FoodMartCreateData-uptodate:

    unzip-FoodMartCreateData:
    [unzip] Expanding: C:\mondrian\demo\FoodMartCreateData.zip into C:\mondrian\demo

    check-FoodMartAccessDB-uptodate:

    unzip-FoodMartAccessDB:
    [unzip] Expanding: C:\mondrian\demo\access\MondrianFoodMart-Access.zip into C:\mondrian\demo\access

    check-FoodMartDerbyDB-uptodate:

    unzip-FoodMartDerbyDB:
    [unzip] Expanding: C:\mondrian\demo\derby\derby-foodmart.zip into C:\mondrian\demo\derby

    unzip-databases:

    all:

    BUILD SUCCESSFUL
    Total time: 32 seconds
</code>
</pre>
</blockquote>
<p>Pay close attention to the Ant targets named compileJdk1.5, compileJdk1.6
    and compileJdk1.7, and ensure that each JVM compilation phase has compiled
    the files it needed to. The JDK 1.5 should compile about 700+ files. The JDK
    1.6 must compile the JDBC 4.0 classes (3 files) and JDK 1.7 should compile
    the JDBC 4.1 driver (1 file). In each compileJdk1.x target, the first target
    is called "apologise:", and must produce no output.</p>

<h2>Installing the database</h2>

<p>Before you run the regression test suite or the web application, you must
install the standard FoodMart dataset. This is described in the
<a href="install.html#2_Set_up_test_data">installation guide</a>.</p>

<p>&nbsp;If you got your files from GitHub, you can skip the step
where you download the data sets: you should already have the files <code>demo/access/MondrianFoodMart.mdb</code>
and <code>demo/FoodMartCreateData.zip</code>.</p>

<p>You will need to update your mondrian.properties in order to connect to the FoodMart database during
the test. The important properties are:</p>

<table style="border-collapse: collapse;" border="1" cellpadding="2" cellspacing="0" id="table1">
  <tbody>
    <tr>
      <th>Property</th><th>Description</th><th>Example (MySQL)</th>
    </tr>
    <tr>
      <td>mondrian.foodmart.jdbcURL</td>
      <td>JDBC URL to connect to your database. Required</td>
      <td>jdbc:mysql://localhost:3307/foodmart</td>
    </tr>
    <tr>
      <td>mondrian.foodmart.jdbcUser</td>
      <td>User name for database connection. Required</td>
      <td>root</td>
    </tr>
    <tr>
      <td>mondrian.foodmart.jdbcPassword</td>
      <td>Password for database connection. Required</td>
      <td>password</td>
    </tr>
    <tr>
      <td>mondrian.jdbcDrivers</td>
      <td>List of paths to JDBC driver JARs as a valid classpath. The paths can be relative to the root of the installation. Required</td>
      <td>testlib/mysql-connector-java-3.1.11-bin.jar</td>
    </tr>
  </tbody>
</table>

<p>There is a target in the build script, load-foodmart, that will load the Foodmart data into an empty
database configured through your mondrian.properties settings. For this target, you can set an additional property
in mondrian.properties, mondrian.foodmart.jdbcSchema=&lt;your schema&gt; if you are using a database that
supports schemas and you want to load Foodmart into a particular schema.</p>


<h2>Running the test suite<a name="6_Run_the_test_suite">&nbsp;</a></h2>

<p>At the command line:</p>

<blockquote>
<code>
cd <i>${project.location}</i><br/>
ant test</code>
</blockquote>

<p>Running the test via the Mondrian Ant build in Eclipse works, too.</p><p>Example output:</p>

<blockquote>
<code>Buildfile: build.xml<br>
Overriding previous definition of reference to jdk<br/>
<br>
prepare:<br>
[mkdir] Created dir: C:\open\mondrian\build<br>
<br>
parser:<br>
[javacup] Opening files...<br>
[javacup] Parsing specification from
C:\open\mondrian\src\main\mondrian\olap\Parser.cup...<br>
[javacup] Checking specification...<br>
[javacup] Warning: Terminal &quot;UNKNOWN&quot; was declared but never used<br>
[javacup] Warning: Non terminal &quot;unsigned_integer&quot; was declared but never used<br>
[javacup] Building parse tables...<br>
[javacup] Computing non-terminal nullability...<br>
[javacup] Computing first sets...<br>
[javacup] Building state machine...<br>
[javacup] Filling in tables...<br>
[javacup] *** Reduce/Reduce conflict found in state #99<br>
[javacup] between value_expression_primary ::= NULL (*)<br>
[javacup] and term3 ::= term3 IS NULL (*)<br>
[javacup] under symbols: {EOF, AND, AS, CELL, DIMENSION, ELSE, END, IN, IS,
MATCHES, MEMBER, NOT, ON, OR, PROPERTIES, SELECT, SE<br>
T, THEN, WHEN, XOR, COLON, COMMA, EQ, GE, GT, LE, LT, NE, RBRACE, RPAREN}<br>
[javacup] Resolved in favor of the second production.<br>
<br>
[javacup] *** Shift/Reduce conflict found in state #99<br>
[javacup] between value_expression_primary ::= NULL (*)<br>
[javacup] under symbol EOF<br>
[javacup] Resolved in favor of shifting.<br>
<br>
...<br>
<br>
[javacup] *** Shift/Reduce conflict found in state #99<br>
[javacup] between term3 ::= term3 IS NULL (*)<br>
[javacup] under symbol RPAREN<br>
[javacup] Resolved in favor of shifting.<br>
<br>
[javacup] Checking for non-reduced productions...<br>
[javacup] Writing parser...<br>
[javacup] Closing files...<br>
[javacup] ------- CUP v0.10k Parser Generation Summary -------<br>
[javacup] 0 errors and 63 warnings<br>
[javacup] 56 terminals, 60 non-terminals, and 125 productions declared,<br>
[javacup] producing 194 unique parse states.<br>
[javacup] 2 terminals declared but not used.<br>
[javacup] 0 non-terminals declared but not used.<br>
[javacup] 0 productions never reduced.<br>
[javacup] 61 conflicts detected (61 expected).<br>
[javacup] Code written to &quot;Parser.java&quot;, and &quot;ParserSym.java&quot;.<br>
[javacup] ---------------------------------------------------- (v0.10k)<br>
<br>
generate.resources:<br>
[javac] Compiling 3 source files to C:\open\mondrian\classes<br>
[resgen] Generating
C:\open\mondrian\src\main\mondrian\resource\MondrianResource.java<br>
[resgen] Generating
C:\open\mondrian\classes\mondrian\resource\MondrianResource.properties<br>
[resgen] Generating
C:\open\mondrian\src\main\mondrian\resource\MondrianResource_en_US.java<br>
[resgen] Generating
C:\open\mondrian\classes\mondrian\resource\MondrianResource_en_US.properties<br>
[resgen] Generating
C:\open\mondrian\src\main\mondrian\resource\MondrianResource_de_DE.java<br>
[resgen] Generating
C:\open\mondrian\classes\mondrian\resource\MondrianResource_de_DE.properties<br>
[resgen] Generating
C:\open\mondrian\src\main\mondrian\resource\MondrianResource_de.java<br>
[resgen] Generating
C:\open\mondrian\classes\mondrian\resource\MondrianResource_de.properties<br>
[resgen] Generating
C:\open\mondrian\src\main\mondrian\resource\MondrianResource_es_ES.java<br>
[resgen] Generating
C:\open\mondrian\classes\mondrian\resource\MondrianResource_es_ES.properties<br>
<br>
def:<br>
[xomgen] Writing src\main\mondrian\olap\mondrian.dtd<br>
[xomgen] Writing src\main\mondrian\olap\MondrianDef.java<br>
[xomgen] Done<br>
[copy] Copying 1 file to C:\open\mondrian\lib<br>
[copy] Copying 1 file to C:\open\mondrian\lib<br>
[xomgen] Writing src\main\mondrian\xmla\datasourcesconfig.dtd<br>
[xomgen] Writing src\main\mondrian\xmla\DataSourcesConfig.java<br>
[xomgen] Done<br>
[copy] Copying 1 file to C:\open\mondrian\lib<br>
<br>
compile.java:<br>
[javac] Compiling 987 source files to C:\open\mondrian\classes<br>
[javac] Note: Some input files use or override a deprecated API.<br>
[javac] Note: Recompile with -Xlint:deprecation for details.<br>
[javac] Note: Some input files use unchecked or unsafe operations.<br>
[javac] Note: Recompile with -Xlint:unchecked for details.<br>
<br>
check-FoodMartCreateData-uptodate:<br>
<br>
unzip-FoodMartCreateData:<br>
[unzip] Expanding: C:\open\mondrian\demo\FoodMartCreateData.zip into
C:\open\mondrian\demo<br>
<br>
check-FoodMartAccessDB-uptodate:<br>
<br>
unzip-FoodMartAccessDB:<br>
[unzip] Expanding: C:\open\mondrian\demo\access\MondrianFoodMart-Access.zip into
C:\open\mondrian\demo\access<br>
<br>
check-FoodMartDerbyDB-uptodate:<br>
<br>
unzip-FoodMartDerbyDB:<br>
[unzip] Expanding: C:\open\mondrian\demo\derby\derby-foodmart.zip into
C:\open\mondrian\demo\derby<br>
<br>
compile:<br>
<br/>
compile.tests:<br/>
&nbsp;&nbsp;&nbsp; [javac] Compiling 69 source files to C:\open\mondrian\testclasses<br/>
&nbsp;&nbsp;&nbsp; [javac] Note: C:\open\mondrian\testsrc\main\mondrian\test\ParameterTest.java uses or overrides a deprecated API.<br/>
&nbsp;&nbsp;&nbsp; [javac] Note: Recompile with -deprecation for details.<br/>
<br/>
test-dbms:<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [echo] Connecting to jdbc:postgresql://localhost/FM3<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: properties loaded from 'file:/C:/open/mondrian/mondrian.properties'<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: properties loaded from 'file:/C:/open/mondrian/build.properties'<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: loaded 4 system properties<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] testName: null<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] testClass: null<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] All 1 thread(s) started.<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: JDBC driver org.postgresql.Driver loaded successfully<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: JDBC driver sun.jdbc.odbc.JdbcOdbcDriver loaded successfully<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: JDBC driver com.mysql.jdbc.Driver loaded successfully<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Mondrian: JDBC driver oracle.jdbc.OracleDriver loaded successfully<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [0] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [40] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [80] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [120] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [160] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [200] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [240] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [280] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [320] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [360] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [400] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [440] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [480] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [520] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [560] ........................................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] [600] ..................<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] OK (618 tests)<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Time: 711.63<br/>
&nbsp;&nbsp;&nbsp;&nbsp; [java] Normal termination.<br/>
BUILD SUCCESSFUL<br/>
Total time: 12 minutes 13 seconds</code></blockquote>

<p/>

<h2>Create, deploy and start the web application</h2>

<p>At the command prompt, type</p>

<blockquote>
	<code>ant war</code>
</blockquote>

<p>This will create <code>lib/mondrian.war</code>. Copy <code>mondrian.war</code>
to the <i></i><code><i>TOMCAT_HOME</i>/webapps</code> directory.</p><p>Now, start Tomcat and hit <a href="http://localhost:8080/mondrian">http://localhost:8080/mondrian</a>.</p>

<h2>Checking in code<a name="Checking_in_code">&nbsp;</a></h2>
<h3>Create a GitHub account</h3>
<p>If you don't have one already, you can create a free GitHub account
    <a href="https://github.com/signup/free">here.</a></p>
<h3>Forking to your account</h3>
<p>The first thing you need to do is fork the Pentaho repository into your GitHub account.
    This creates an exact copy of the Pentaho repo as it exists at the time of the
    fork in your personal GitHub space. This copy is not updated as the Pentaho
    repository gets updated, but we&apos;ll cover how to keep it updated later.</p>

<p>From the Mondrian repository page click the Fork button near the top right.
    Once you have done this, GitHub will redirect you to your newly forked repository.</p>

<h3>Cloning a specific branch</h3>
<p>Mondrian works on a single repository with multiple branches containing the
    different versions &ndash; past, released and in development. <b>You should never be
        working against the master branch without permission from the Mondrian development
        team.</b> Always work against the repository specific to the version you are developing for.
    Cloning the repository moves all the data and metadata from all branches to your
    local working folder, and you then checkout a specific branch locally to
    setup the file structure for that version.</p>

<p>First, clone the repository:<br></p><pre>
<code>$ git clone https://github.com/[username]/mondrian.git</code></pre><pre>
    <code>Cloning into 'mondrian'...
    remote: Counting objects: 51661, done.
    remote: Compressing objects: 100% (9979/9979), done.
    remote: Total 51661 (delta 37833), reused 51512 (delta 37691)
    Receiving objects: 100% (51661/51661), 294.25 MiB | 604 KiB/s, done.
    Resolving deltas: 100% (37833/37833), done.</code></pre>
<p>Now change into the newly created &apos;mondrian&apos; folder and list the
    available branches:<br></p><pre><code>$ git branch -a</code></pre><pre>
    <code>master
    remotes/origin/3.0
    remotes/origin/3.1
    remotes/origin/3.2
    remotes/origin/3.2.2
    remotes/origin/3.3.1
    remotes/origin/3.4
    remotes/origin/HEAD -&gt; origin/master
    remotes/origin/lagunitas
    remotes/origin/master
    remotes/origin/pacino</code></pre>
<p>And finally checkout the branch you want to work on:<br></p>
<pre><code>$ git checkout 3.4</code></pre><pre>
    <code>Branch 3.4 set up to track remote branch 3.4 from origin.
    Switched to a new branch '3.4'</code></pre>

<h3>Adding upstream and local settings</h3>
<p>In order to be able to keep your repository up-to-date with the Pentaho
    Mondrian repository, and to be able to merge your changes with changes made
    while you were developing your feature, we will add a new remote called
    &apos;upstream&apos; that will point to the Pentaho repository directly.</p>
<pre><code>$ git remote add upstream git://github.com/pentaho/mondrian.git</code></pre>
<p>You also want to disable fast-forward during merges to preserve the entire commit history and properly track file changes.</p>
<pre><code>$ git config --add merge.ff false</code></pre><p><strong>Note:</strong> If you have a git version prior to 1.7.6, this option will do nothing.</p>
<p><strong>Your repository is now ready to develop against your selected branch.</strong></p>

<h3>Merging upstream changes</h3>
<p>It is important during development that you keep your repository updated with
    any changes made to the Pentaho Mondrian repository.  This not only ensures
    that you are always working with the most recent code available for your
    working branch, but also ensures that your changes do not break any new or
    updated tests.</p>
<p>To update and merge changes from the upstream repository, do the following:<br></p>
<pre><code>$ git fetch upstream [branch]
$ git merge upstream/[branch]</code></pre>
<p>Where [branch] is the current branch you&apos;re working on.</p>
<p>If you are using a version of git prior to 1.7.6, you need to add the
    <em>&ndash;&ndash;no&ndash;ff</em> flag in order to disable fast&ndash;forward merges:<br></p><pre>
<code>$ git merge --no-ff upstream/[branch]</code></pre>
<p>If there are any merge conflicts, git will let you know.
    Otherwise, your local repository is now up-to-date without losing any of
    your working changes.</p>
<p>This should always be the 2nd last step performed before issuing a pull request.
    The last step being, of course, running the tests again after the merge to
    ensure nothing is broken.</p>
<h3>Preparing for a Pull Request</h3>
<p>Before starting a pull request, please make sure the following criteria are
    met or your request may not be accepted and merged, or may take much longer
    to be merged into the Pentaho Mondrian repository.</p>
<ol>
    <li><b>Make sure your change adheres to the <a href="#Coding_guidelines">
        coding guidelines</a></b>.  To verify that your contribution conforms to
        those standards, you can use the
        <a href="#The_checkFile_utility">checkFile</a> utility.
    <li><b>Write a unit test for your change</b>. (Or unit tests: the number of
        unit tests you write should be appropriate for the scale of your change.)
        The test should fail before you make the change, and succeed after it. We
        recommend a test-driven development process, where you write the test before
        you change the code. Unit tests are particularly important if you are fixing
        a bug.</li>
    <li><b>Run the regression suite, and make sure all tests pass</b>. We don't
        expect you to run the suite in all configurations (DBMSes, operating
        systems, JDK versions, and parameter settings) but if your change affects
        something configuration-specific, be smart and test more than one
        configuration. For example, SQL generation is DBMS-specific, and file
        handling is OS-specific, but MDX function implementations are typically
        generic.</li>
    <li><b>If the change affects mondrian's user-visible behavior, update the
        documentation</b>. For example, if you make a schema change, update
        <a href="schema.html">schema.html</a>.</li>
    <li><b>If your change affects a public API, discuss the change with mondrian
        developers first</b>. We want to preserve backwards compatibility if
        possible, or at least clearly document the change in the release notes.</li>
    <li><b>Use JIRA case numbers in your commit messages</b>. If your
        change fixes a bug, reference the bug number in your commit message, and
        reference the commit hash value and expected release number
        in the bug comments when closing the bug.</li>
</ol>

<h3>Generating a Pull Request</h3>
<p>A pull request is the way GitHub manages the process of merging changes
    between forked repositories.  Generating a pull request starts a conversation
    with the Pentaho Mondrian development team asking them to review the changes
    you&apos;ve made, comment on them, and optionally choose to merge the changes
    into the main repository or return them to you for additional changes.</p>
<p>When you are ready to start a pull request, go to your personal Mondrian
    fork on GitHub and select the branch you want to be merged.  Then click the
    Pull Request button near the top of the page.<br>
    <img src="https://a248.e.akamai.net/camo.github.com/167ecedbd6d84db343817b0d7958fbe03ebcdcd8/687474703a2f2f696d672e736b697463682e636f6d2f32303130303833312d71666b316339777974383970666766786736316268317238726e2e706e67" title="pull request" alt="pull request"></p>
<p>You can then fill in a title and notes related to the pull request, and
    click the <em>Send pull request</em> button.  The Mondrian development team
    will be notified of the pull request and will continue the process from there.</p>
<p>For a more detailed description of the entire pull request and commenting process,
    see <a href="http://help.github.com/send-pull-requests/">Help.GitHub &ndash; Send pull requests</a></p>


<h2>Coding guidelines<a name="Coding_guidelines">&nbsp;</a></h2><p>If you are contributing code, please follow the same guidelines used for the
rest of the code. (&quot;When in Rome, do as the Romans do.&quot;)</p><p>Code content:</p><ul>
  <li>Declare variables as near to their first use as possible.</li><li>Don't initialize variables with 'dummy' values just
      to shut up the compiler.</li><li>One declaration per line is recommended.</li><li>Only one top-level class should be defined per java file.</li></ul><p>Documentation and comments:</p><ul>
  <li>Source files must contain copyright and license notices.</li><li>Classes and public methods must have javadoc.</li><li>Write Javadoc comments on
      methods in the present active ('Collects garbage.'), <em>not</em>
      the imperative ('Collect garbage.'), passive ('Garbage is collected.'),
      or future active ('Will collect garbage.').</li><li>When editing HTML documents, please don't use an editor which reformats
      the HTML source (such as Microsoft Word).</li></ul><p>Spacing and indentation:</p><ul>
  <li>Use spaces, not tabs.</li><li>Indentation 4.</li><li>Open braces on the same line as the preceding 'if', 'else', 'while'
      statement, or method or 'class' declaration.</li><li>Use braces even for single-line blocks.</li><li>Try to keep lines shorter than 80 characters.</li></ul><p>The following images show my
code style settings in IntelliJ. If you use IntelliJ, plug in these settings; if
not, they should give you an idea of the code formatting policy.</p>

<p><img border="0" alt="Code formatting: General" src="images/code_general.png" width="1007" height="826"></p>

<p><img border="0" alt="Code formatting: Alignment and Braces" src="images/code_indentation.png" width="1007" height="866"></p>

<p><img border="0" alt="Code formatting: Wrapping" src="images/code_wrapping.png" width="1007" height="866"></p>

<p><img border="0" alt="Code formatting: Spaces" src="images/code_spacing.png"></p>

<h2>The checkFile utility<a name="The_checkFile_utility">&nbsp;</a></h2>

<p>If the files you are submitting do not pass the checkFile utility, your pull
    request may be delayed or denied.  It is recommended that you run checkFile
    locally before initiating a pull request.  The utility is located in your git
    repository under the bin directory.
    <a href="https://github.com/pentaho/mondrian/tree/master/bin/checkFile">
        <code>https://github.com/pentaho/mondrian/tree/master/bin/checkFile</code></a>
    The script requires <a href="http://www.cygwin.com">cygwin</a> to run on
    Windows.</p>
<p>Usage:</p>
<pre><code>
checkFile  [ &lt;options&gt; ] &lt;file&gt;...
    Checks a list of files.
checkFile  [ &lt;options&gt; ] --opened
    Checks all files that are opened in git. Implies --strict.
checkFile  [ &lt;options&gt; ] --under &lt;dir&gt;
    Recursively checks all files under a given directory.
checkFile --help
    Prints this help.

Options:
--lenient
    Does not apply rules to components which are not known to
    be in compliance.
--strict
    Stricter than usual; the opposite of lenient.
</code></pre>
<h2>Learning more about Mondrian<a name="Learning_more_about_Mondrian">&nbsp;</a></h2>

<h3>How Mondrian generates SQL<a name="How_Mondrian_generates_SQL">&nbsp;</a></h3>

<p>If you're feeling mystified where the various SQL statements come
from, here's a good way to learn more. Give it a try, and if you have
more questions I'll be glad to answer them.</p><p>In a debugger, put a break point in the <code>
<a href="api/mondrian/rolap/RolapUtil.html#executeQuery(java.sql.Connection, java.lang.String, java.lang.String)">RolapUtil.executeQuery()</a></code>
method, and run a
simple query. The easiest way to run a query is to run a junit testcase such as
<a href="api/mondrian/test/BasicQueryTest.html#testSample0()">BasicQueryTest.testSample0()</a>.
The debugger will stop every time a SQL
statement is executed, and you should be able to loop up the call stack to which component is executing the query.</p><p>I expect that you will see the following phases in the execution:<ul>

<li>One or two SQL queries will be executed as the <code>schema.xml</code> file is read
(validating calculated members and named sets, resolving default members of
hierarchies, and such)<li>A few SQL queries will be executed to resolve members as the query
is parsed. (For example, if a query uses <code>[Store].[USA].[CA]</code>, it will
look all members of the <code>[Store Nation]</code> level, then look up all children
of the <code>[USA]</code> member.)

<li>When the query is executed, the axes (slicer, columns, rows) are
executed first. Expect to see more queries on dimension tables when
expressions like <code>[Product].children</code> are evaluated.

<li>Once the axes are populated, the cells are evaluated. Rather than
executing a SQL query per cell, Mondrian makes a pass over all cells
building a list of cells which are not in the cache. Then it builds
and executes a SQL query to fetch all of those cells. If it didn't
manage to fetch all cell values, it will repeat this step until it
does.</li></ul></p><p>Remember that the purpose of these queries is to populate cache. There are two caches. The dimension cache which maps a member to its children, e.g.</p><blockquote><code>[Store].[All Stores]</code>&nbsp;&rarr; <code>{ [Store].[USA], [Store].[Canada], [Store].[Mexico]}</code></blockquote><p>The aggregation cache maps a tuple a measure value, e.g.</p><blockquote><code>([Store].[USA], [Gender].[F], [Measures].[Unit Sales])</code>
	&rarr; <code>123,456</code></blockquote><p>Once the cache has been populated, the query won't be executed
again. That's why I recommend that you restart the process each time
you run this in the debugger.</p>

<hr noshade size="1"/>
<p>
    Author: Julian Hyde; last updated August, 2011.<br/>
    Version: $Id$
    (<a href="http://p4web.eigenbase.org/open/mondrian/doc/developer.html?ac=22">log&nbsp;</a>)<br/>
    Copyright (C) 2005-2011 Pentaho
</p>

<br />

<!-- doc2web end -->

</body>
</html>
